import pandas as pd
import os
from datetime import datetime
import re

class LeaveRecord:
    def __init__(self, employee_id_column='工号', name_column='请假人', start_date_column='请假开始时间', end_date_column='请假结束时间'):
        self.file_path = os.path.join(os.path.dirname(__file__), '../img/pmg.xlsx')
        self.employee_id_column = employee_id_column
        self.name_column = name_column
        self.start_date_column = start_date_column
        self.end_date_column = end_date_column

        self.leave_data = self._load_and_clean_data()

    def _parse_date(self, date_str, is_start_date=True):
        """尝试解析日期字符串，支持多种格式根据日期中的'(上午)'或'(下午)'后缀设置相应的具体时间：
            - 开始日期上午: 00:00
            - 结束日期上午: 14:00
            - 开始日期下午: 14:00
            - 结束日期下午: 24:00

        参数:
            date_str: 日期字符串
            is_start_date: 是否为开始日期，True为开始日期，False为结束日期
            

        返回:
            datetime: 解析后的日期时间对象
        """
        if pd.isna(date_str):
            return None

        date_str = str(date_str)
        # 检查是否包含上午或下午
        is_am = '上午' in date_str
        is_pm = '下午' in date_str

        # 移除(上午)、(下午)等后缀
        date_str = re.sub(r'\(.*?\)', '', date_str).strip()
        date_str = date_str.replace('上午', '').replace('下午', '').strip()

        # 尝试标准格式
        try:
            base_date = pd.to_datetime(date_str)
        except:
            # 尝试常见的中文日期格式
            date_formats = ['%Y年%m月%d日', '%Y-%m-%d', '%m/%d/%Y', '%d-%m-%Y']
            base_date = None
            for fmt in date_formats:
                try:
                    base_date = datetime.strptime(date_str, fmt)
                    break
                except:
                    continue

            # 尝试提取数字并转换
            if base_date is None:
                try:
                    numbers = re.findall(r'\d+', str(date_str))
                    if len(numbers) >= 3:
                        # 假设格式为年月日
                        base_date = datetime(int(numbers[0]), int(numbers[1]), int(numbers[2]))
                except:
                    pass

        if base_date is None:
            return None

        # 根据上午/下午设置具体时间
        #开始日期规则
        if is_start_date:
            if is_am:
                # 开始日期是上午，设置为08:30
                return base_date.replace(hour=0, minute=0, second=0, microsecond=0)
            elif is_pm:
                # 开始日期是下午，设置为14:00
                return base_date.replace(hour=12, minute=0, second=0, microsecond=0)
            else:
                # 默认开始时间为08:30
                return base_date.replace(hour=0, minute=0, second=0, microsecond=0)
        else:#结束日期规则
            if is_am:
                # 结束日期是上午，设置为12:00
                return base_date.replace(hour=14, minute=0, second=0, microsecond=0)
            elif is_pm:
                # 结束日期是下午，设置为17:30
                return base_date.replace(hour=23, minute=59, second=59, microsecond=0)
            else:
                # 默认结束时间为17:30
                return base_date.replace(hour=23, minute=59, second=59, microsecond=0)

        return base_date

    def _load_and_clean_data(self):
        """读取Excel文件并删除重复记录"""
        try:
            # 读取"休假"工作表
            df = pd.read_excel(self.file_path, sheet_name='休假')

            # 打印列名，帮助调试
            #print(f"Excel文件中的列名: {df.columns.tolist()}")

            # 检查是否存在必要的列
            required_columns = [self.employee_id_column, self.start_date_column, self.end_date_column]
            missing_columns = [col for col in required_columns if col not in df.columns]
            if missing_columns:
                print(f"缺少必要的列: {missing_columns}")
                return pd.DataFrame()

            # 删除工号为'工号'的非法记录
            initial_count = len(df)
            df = df[df[self.employee_id_column] != '工号']
            deleted_count = initial_count - len(df)
            # if deleted_count > 0:
            #     print(f"删除了 {deleted_count} 条工号为'工号'的非法记录")

            # 按工号和开始日期删除重复记录
            df.drop_duplicates(subset=[self.employee_id_column, self.start_date_column], inplace=True)
            #print(f"删除重复记录后剩余 {len(df)} 条")


            # 尝试转换日期列
            try:
                # 使用自定义函数转换开始日期（设置is_start_date=True）
                df[self.start_date_column] = df[self.start_date_column].apply(lambda x: self._parse_date(x, is_start_date=True))
                # 使用自定义函数转换结束日期（设置is_start_date=False）
                df[self.end_date_column] = df[self.end_date_column].apply(lambda x: self._parse_date(x, is_start_date=False))

                # 删除日期转换失败的行
                df.dropna(subset=[self.start_date_column, self.end_date_column], inplace=True)

                if df.empty:
                    print("所有日期转换失败，数据为空")
                    return pd.DataFrame()
                else:
                    print(f"成功转换 {len(df)} 条记录的日期")

            except Exception as e:
                print(f"日期转换失败: {str(e)}")
                return pd.DataFrame()

            return df
        except Exception as e:
            print(f"读取请假记录失败: {str(e)}")
            return pd.DataFrame()

    def is_on_leave(self, employee_id:str, check_date:datetime):
        """
        检查员工在指定日期时间是否请假

        参数:
            employee_id: 工号
            check_date: 检查日期时间，格式为'YYYY-MM-DD HH:MM:SS'或datetime对象

        返回:
            bool: 如果请假返回True，否则返回False
        """
        if self.leave_data.empty:
            return False

        # 查找该员工的所有请假记录
        employee_leaves = self.leave_data[self.leave_data[self.employee_id_column] == employee_id]

        # 检查是否有涵盖check_date的请假记录
        for _, leave in employee_leaves.iterrows():
            start_datetime = leave[self.start_date_column]
            end_datetime = leave[self.end_date_column]
            if start_datetime <= check_date <= end_datetime:
                return True

        return False

    def is_on_leave_by_name(self, name:str, check_date:datetime):
        """
        检查员工在指定日期时间是否请假（通过姓名查询）

        参数:
            name: 姓名
            check_date: 检查日期时间，格式为'YYYY-MM-DD HH:MM:SS'或datetime对象

        返回:
            bool: 如果请假返回True，否则返回False
        """
        if self.leave_data.empty:
            return False

        # 查找该姓名的所有员工记录
        name_matches = self.leave_data[self.leave_data[self.name_column] == name]

        if name_matches.empty:
            return False

        # 取第一个匹配的员工工号
        employee_id = name_matches.iloc[0][self.employee_id_column]

        # 调用is_on_leave方法检查是否请假
        return self.is_on_leave(employee_id, check_date)

if __name__ == "__main__":
    leave_record = LeaveRecord()
    print(leave_record.is_on_leave_by_name("彭国安", "2025-08-09"))
    print(leave_record.is_on_leave("033064", "2025-08-04"))
